



#include <cegfx/cemorphmesh.h>

using std::vector;

ceMorphMesh::ceMorphMesh ()
	: numVertices(0)
	, indexBuffer (0)
	, numTriangles (0)
	, vertexDeclaration(0)
	, stride (0)
	, idx0(0)
	, idx1(1)
	, interpol(0.0f)
{
	vertexBuffers.clear ();
}

ceMorphMesh::~ceMorphMesh ()
{
	vector<LPDIRECT3DVERTEXBUFFER9>::iterator it;
	for (it = vertexBuffers.begin (); it != vertexBuffers.end (); it++)
	{
		(*it)->Release ();
	}
	vertexBuffers.clear ();

	if (indexBuffer)
	{
		indexBuffer->Release ();
	}
	if (vertexDeclaration)
	{
		vertexDeclaration->Release ();
	}
}

IQF_IMPLEMENTATION_BEGIN (ceMorphMesh);
IQF_IMPLEMENTATION_INTERFACE(iGeometry);
IQF_IMPLEMENTATION_INTERFACE(iMorphMesh);
IQF_IMPLEMENTATION_END ();


void ceMorphMesh::AddVertices (LPDIRECT3DVERTEXBUFFER9 vertexBuffer, unsigned numVertices)
{
	if (vertexBuffer)
	{
		vertexBuffer->AddRef ();
	}
	this->vertexBuffers.push_back (vertexBuffer);
	this->numVertices = numVertices;
}

void ceMorphMesh::AddVertices (LPDIRECT3DVERTEXBUFFER9 vertexBuffer)
{
	if (vertexBuffer)
	{
		vertexBuffer->AddRef ();
	}
	this->vertexBuffers.push_back (vertexBuffer);
}

LPDIRECT3DVERTEXBUFFER9 ceMorphMesh::GetVertexBuffer (unsigned idx)
{
	return vertexBuffers[idx];
}

const LPDIRECT3DVERTEXBUFFER9 ceMorphMesh::GetVertexBuffer (unsigned idx) const
{
	return vertexBuffers[idx];
}

unsigned ceMorphMesh::GetNumVertices () const
{
	return numVertices;
}

unsigned ceMorphMesh::GetNumberOfMorphFrames () const
{
	return vertexBuffers.size ();
}

void ceMorphMesh::SetVertexDeclaration (LPDIRECT3DVERTEXDECLARATION9 declaration, unsigned stride)
{
	if (declaration)
	{
		declaration->AddRef ();
	}
	if (vertexDeclaration)
	{
		vertexDeclaration->Release ();
	}

	vertexDeclaration = declaration;
	this->stride = stride;
}

LPDIRECT3DVERTEXDECLARATION9 ceMorphMesh::GetVertexDeclaration ()
{
	return vertexDeclaration;
}

const LPDIRECT3DVERTEXDECLARATION9 ceMorphMesh::GetVertexDeclaration () const
{
	return vertexDeclaration;
}

unsigned ceMorphMesh::GetStride () const
{
	return stride;
}

void ceMorphMesh::SetIndices (LPDIRECT3DINDEXBUFFER9 indexBuffer, unsigned numTriangles)
{
	if (indexBuffer)
	{
		indexBuffer->AddRef ();
	}
	if (this->indexBuffer)
	{
		this->indexBuffer->Release ();
	}
	this->indexBuffer = indexBuffer;
	this->numTriangles = numTriangles;
}

LPDIRECT3DINDEXBUFFER9 ceMorphMesh::GetIndexBuffer ()
{
	return indexBuffer;
}

const LPDIRECT3DINDEXBUFFER9 ceMorphMesh::GetIndexBuffer () const
{
	return indexBuffer;
}

unsigned ceMorphMesh::GetNumberOfTriangles () const
{
	return numTriangles;
}



void ceMorphMesh::Render (const ceRenderEnv& env)
{
	LPDIRECT3DDEVICE9 device = env.device;
	device->SetVertexDeclaration (vertexDeclaration);
	device->SetStreamSource (0, vertexBuffers[idx0], 0, stride);
	device->SetStreamSource (1, vertexBuffers[idx1], 0, stride);
	device->SetIndices (indexBuffer);
	device->DrawIndexedPrimitive (D3DPT_TRIANGLELIST, 0, 0, numVertices, 0, numTriangles);
}


void ceMorphMesh::Update (const ceUpdateEnv& env)
{
}


const ceBoundingBox& ceMorphMesh::GetBoundingBox () const
{
	return boundingBox;
}


void ceMorphMesh::SetMorphFrame (unsigned frame0, unsigned frame1, float interpol)
{
	idx0 = frame0;
	idx1 = frame1;
	this->interpol = interpol;
}

